<template>
    <div class="treeEdit">
        <custom-el-tree v-get-ref="getRefFn" :data="treeData" :empty-text="treeOptions.emptyText"
                        :node-key="treeOptions.nodeKey" :ref="treeOptions.ref"
                        :render-after-expand="treeOptions.renderAfterExpand"
                        :highlight-current="treeOptions.highlightCurrent"
                        :default-expand-all="treeOptions.defaultExpandAll"
                        :expand-on-click-node="treeOptions.expandOnClickNode"
                        :check-on-click-node="treeOptions.checkOnClickNode"
                        :auto-expand-parent="treeOptions.autoExpandParent"
                        :default-expanded-keys="defaultExpandedKeys"
                        :show-checkbox="treeOptions.showCheckbox"
                        :check-strictly="treeOptions.checkStrictly"
                        :default-checked-keys="defaultCheckedKeys"
                        :current-node-key="currentNodeKey"
                        :accordion="treeOptions.accordion" :indent="treeOptions.indent"
                        :icon-class="treeOptions.iconClass" :lazy="treeOptions.lazy"
                        :draggable="treeOptions.draggable" :props="treeOptions.props"
                        :allow-drop="allowDrop" :load="load"
                        :render-content="renderContent"
                        :filter-node-method="filterNode"
                        class="custom-handle-outer"
                        @node-click="handleNodeClick"
                        @check="handleCheck"
                        @check-change="handleCheckChange" />
    </div>
</template>

<script>
export default {
    name: "vTreeEdit",
    components: {
        CustomElTree: () => import("../custom/ElTree"),
    },
    inject: {
        setChildrenRef: {
            default: () => {
            },
        },
    },
    props: {
        options: {
            type: Object,
            default() {
                return {};
            },
        },
        treeData: {
            type: Array,
            default() {
                return [];
            },
        },
        //默认展开目录
        defaultExpandedKeys: {
            type: Array,
            default() {
                return [];
            },
        },
        //默认勾选节点
        defaultCheckedKeys: {
            type: Array,
            default() {
                return [];
            },
        },
        // 当前选中的节点
        currentNodeKey: {
            type: [String, Number],
            default: null,
        },
    },
    data() {
        return {
            // defaultExpandedKeys: [], //默认展开的节点的 key 的数组
            // defaultCheckedKeys: [], //默认勾选的节点的 key 的数组
            // filterText: '',
            treeOptions: {},
            defaultOptions: {
                emptyText: "暂无数据", //内容为空的时候展示的文本
                nodeKey: "id", //树节点唯一标识
                ref: "tree",
                props: {
                    //配置选项
                    children: "children", //指定子树为节点对象的某个属性值
                    label: "label", //指定节点标签为节点对象的某个属性值
                    // disabled: "dr", //指定节点选择框是否禁用为节点对象的某个属性值boolean, function(data, node)
                    // isLeaf: "isLeaf", //指定节点是否为叶子节点，仅在指定了 lazy 属性的情况下生效boolean, function(data, node)
                },
                renderAfterExpand: true, //是否在第一次展开某个树节点后才渲染其子节点
                highlightCurrent: false, //是否高亮当前选中节点
                defaultExpandAll: false, //是否默认展开所有节点
                expandOnClickNode: true, //是否在点击节点的时候展开或者收缩节点， 默认值为 true，如果为 false，则只有点箭头图标的时候才会展开或者收缩节点。
                checkOnClickNode: false, //是否在点击节点的时候选中节点，默认值为 false，即只有在点击复选框时才会选中节点
                autoExpandParent: true, //展开子节点的时候是否自动展开父节点
                showCheckbox: false, //节点是否可被选择
                checkStrictly: false, //在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false
                accordion: false, //是否每次只打开一个同级树节点展开
                indent: 16, //相邻级节点间的水平缩进，单位为像素
                iconClass: "", //自定义树节点的图标
                lazy: false, //是否懒加载子节点，需与 load 方法结合使用
                draggable: false, //是否开启拖拽节点功能
                buttons: [
                    //右侧按钮
                    // {
                    //   icon: "el-icon-circle-plus-outline",
                    //   method: (data, $event) => {
                    //     this.add(data, $event);
                    //   },
                    // },
                ],
                iconField: 'icon',
            },
        };
    },
    watch: {
        options: {
            handler() {
                this.initOptions(this.options);
            },
            deep: true,
            immediate: true,
        },
    },
    created() {
        let _this = this;
        _this.initOptions(_this.options);
    },
    methods: {
        getRefFn(v) {
            typeof this.setChildrenRef === 'function' && this.setChildrenRef(this.treeOptions.ref, v);
        },
        getCurrentNode() {
            let ref = this.$refs[this.treeOptions.ref];
            this.$emit("event", {
                type: "cellClick",
                ref,
            });
        },
        initOptions(options) {
            this.treeOptions = $.extend({}, this.defaultOptions, options);
        },
        allowDrop(draggingNode, dropNode, type) {
            // 拖拽时判定目标节点能否被放置。type 参数有三种情况：'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
            // console.log(
            //   "(draggingNode, dropNode, type)",
            //   draggingNode,
            //   dropNode,
            //   type
            // );
            return true;
        },
        load(node, resolve) {
            //加载子树数据的方法，仅当 lazy 属性为true 时生效
            if (
                this.treeOptions.load &&
                typeof this.treeOptions.load === "function"
            ) {
                return this.treeOptions.load(node, resolve);
            }
            return resolve();
        },
        filterNode(value, data) {
            // 对树节点进行筛选时执行的方法，返回 true 表示这个节点可以显示，返回 false 则表示这个节点会被隐藏
            if (
                this.treeOptions.filterNode &&
                typeof this.treeOptions.filterNode === "function"
            ) {
                return this.treeOptions.filterNode(value, data);
            }
            return true;
        },
        renderContent(h, { node, data, store }) {
            // 树节点的内容区的渲染
            if (
                this.treeOptions.renderContent &&
                typeof this.treeOptions.renderContent === "function"
            ) {
                return this.treeOptions.renderContent(h, { node, data, store });
            }
            let icon = undefined;
            const iconValue = data[this.treeOptions.iconField];
            if (this.$utils.isNotEmpty(iconValue)) {
                icon = this.$utils.getFileUrl(iconValue);
            }
            return (
                <div class="custom-handle-node">
                    { icon ? (<div class="icon"><img src={icon} alt="" /></div>):'' }
                    <div class="label-tr">{ node.label }</div>
                    { this.treeOptions.buttons && this.treeOptions.buttons.length ? (
                        <div class="btn-tr">
                            { this.treeOptions.buttons.map((item) => {
                                if (!item.filter || item.filter(data, item)) {
                                    return (
                                        <i
                                            class={ item.icon }
                                            v-permission={ item.permission }
                                            on-click={ ($event) => {
                                                $event.stopPropagation();
                                                item.method(data, $event);
                                            } }
                                        ></i>
                                    );
                                } else return "";
                            }) }
                        </div>
                    ) : (
                        ""
                    ) }
                </div>
            );
        },
        handleCheck(data, node) {
            // console.log(data,node,)
        },
        handleCheckChange(data, checked, indeterminate) {
            //节点选中状态发生变化时的回调传递给 data 属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点
            // console.log("data", data, checked, indeterminate);
            let ref = this.$refs[this.treeOptions.ref];
            this.$emit("event", {
                type: "checkClick",
                ref,
                data, checked, indeterminate
            });
        },
        handleNodeClick(data, node) {
            // 节点被点击时的回调
            let ref = this.$refs[this.treeOptions.ref];
            this.$emit("event", {
                type: "nodeClick",
                ref,
                data,
                node,
            });
        },
        filterTextSearch(val) {
            if (this.treeOptions.ref) {
                this.$refs[this.treeOptions.ref].filter(val);
            }
        },
    },
};
</script>
<style lang="less" rel="stylesheet/less" scoped>
.treeEdit {
    width: 100%;
    overflow: auto;
    //display: flex;
    height: 100%;
    box-sizing: border-box;
    // padding: 5px 10px;
    background-color: #fff;
    font-size: 14px;

    .el-tree {
        width: 100%;
        display: inline-table;
        flex-wrap: wrap;
        align-items: flex-start;
    }

    /deep/.tree-node-icon {
        width: 24px;
        text-align: center;
    }

    /deep/.custom-handle-outer {
        .el-tree-node {
            .el-tree-node__content {
                display: flex;
                align-items: center;
                line-height: 1;
            }

            &.is-current {
                > .el-tree-node__content {
                    background-color: #409effb3;
                    color: #fff;
                }
            }
        }
    }

    /deep/.custom-handle-node {
        flex-grow: 1;
        display: flex;
        align-items: center;
        // justify-content: space-between;

        .label-tr {
            position: relative;
        }

        .rent-icon {
            position: absolute;
            left: -20px;
            top: 1px;
        }

        .icon {
            padding-right: 5px;

            img {
                width: 18px;
                height: 18px;
            }
        }

        .btn-tr {
            // display: none;
            margin-left: 5px;
            opacity: 0;
            pointer-events: none;

            i {
                margin: 0 2px;
                padding: 0 2px;
            }
        }

        &:hover {
            .btn-tr {
                // display: block;
                opacity: 1;
                pointer-events: initial;
            }
        }
    }
}
</style>
